<!DOCTYPE html>
<html>
<head>
  <title>网络划分计算</title>
</head>
<body>
  <h1>网络划分计算结果</h1>

   
  <label for="networkAddress">网络地址:</label>
  <input type="text" id="networkAddress" value="192.168.1.0"><br>

  <label for="subnetMaskBits">子网掩码位数:</label>
  <input type="number" id="subnetMaskBits" value="27"><br>
  
  <button onclick="calculateNetworkSegments()">计算</button>

  <div id="result"></div>

  <script>
    function getIpFront3(parts){
        let res=""
 for(let i=0;i<3;i++){
    res+=parts[i]+"."
 }
 return res
    }
    function calculateNetworkSegments() {

      const networkAddress = document.getElementById("networkAddress").value;
      const subnetMaskBits = parseInt(document.getElementById("subnetMaskBits").value);

      // const networkAddress = "192.168.1.0";
      // const subnetMaskBits = 27;
   let jie=   subnetMaskBits - 24
   let  parts= networkAddress.split(".")
//    for(let )
let  IpFront3=
getIpFront3(parts)
let  hostCnt=Math.pow(2,8-jie)
   console.log(`子网数2^jie=  2^${jie}= ${Math.pow(2,jie)}  主机容量=2^(8-jie) =2^(8-${jie}) =2^5=${hostCnt}`);
      const totalSubnets = Math.pow(2, subnetMaskBits - 24);
      const hostsPerSubnet = Math.pow(2, 32 - subnetMaskBits);
      let result = "<h2>网络划分详情</h2>";
      let  resultDom=  document.getElementById("result")
      resultDom.innerHTML+=`子网数2^jie=  2^${jie}= ${Math.pow(2,jie)}  主机容量=2^(8-jie) =2^(8-${jie}) =2^5=${Math.pow(2,8-jie)}\n`

    //   https://blog.csdn.net/LiuHuan303/article/details/119328221
    // let  networkAddressNow=
    let  networkAddressLastNow=0
    // 网络号和广播地址分别是：
    resultDom.innerHTML+=`<p>网络号和广播地址分别是：</p>\n`
      for (let i = 0; i < totalSubnets; i++) {
        const subnetStart = i * hostsPerSubnet;
        const subnetEnd = subnetStart + hostsPerSubnet - 1;
        // const network = `${IpFront3}.${networkAddressLastNow}/${subnetMaskBits}`;
        const network = `${IpFront3}${networkAddressLastNow}/${subnetMaskBits}`;

        networkAddressLastNow+=hostCnt
        // const network = `${networkAddress}/${subnetMaskBits}`;
        // const broadcast = `${subnetEndToIpAddress(subnetEnd)}/${subnetMaskBits}`;
        const broadcast = `${IpFront3}${networkAddressLastNow-1}/${subnetMaskBits}`;

        result += `<p>${network} ---- ${broadcast}</p>`;
      }

    //   document.getElementById("result").innerHTML = result;
      resultDom.innerHTML+=result+"\n"
    }

    function subnetEndToIpAddress(end) {
      const octets = [];
      for (let i = 3; i >= 0; i--) {
        const octet = Math.floor(end / Math.pow(256, i));
        octets.push(octet);
        end = end % Math.pow(256, i);
      }
      return octets.join(".");
    }

    // calculateNetworkSegments();

    function summarizeNetworks(ipAddresses) {
  // 将 IP 地址转换为二进制表示形式的数组
  const binaryIPs = ipAddresses.map(ip => ipToBinary(ip));

  console.log("binaryIPs");
  console.log(binaryIPs);

  // 找到不相同位置的索引
  let index = 0;
  while (index < binaryIPs[0].length && allBitsEqual(binaryIPs, index)) {
    index++;
  }

  // 构建网络汇总的网段
  const networkAddress = binaryIPs[0].slice(0, index) + "0".repeat(32 - index);
  const subnetMaskBits = index;

  // 返回网段表示
  return `${binaryToIP(networkAddress)}/${subnetMaskBits}`;
}

// 辅助函数：将 IP 地址转换为二进制表示形式
function ipToBinary(ip) {
  return ip.split(".").map(part => parseInt(part).toString(2).padStart(8, "0")).join("");
}

// 辅助函数：检查给定索引位置的比特是否在所有 IP 地址中都相等
function allBitsEqual(binaryIPs, index) {
  const bit = binaryIPs[0][index];
  for (let i = 1; i < binaryIPs.length; i++) {
    if (binaryIPs[i][index] !== bit) {
      return false;
    }
  }
  return true;
}

// 辅助函数：将二进制表示形式的 IP 地址转换为常规表示形式
function binaryToIP(binaryIP) {
  const octets = [];
  for (let i = 0; i < 32; i += 8) {
    const octet = parseInt(binaryIP.slice(i, i + 8), 2);
    octets.push(octet);
  }
  return octets.join(".");
}

// 测试
const ipAddresses = ["192.168.1.0", "192.168.3.0", "192.168.5.0"];
const summary = summarizeNetworks(ipAddresses);
console.log("summary"); // 输出: 192.168.0.0/21
console.log(summary); 
  </script>
</body>
</html>
